home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Graphics Programming (2nd Edition)
/
Visual Basic Graphics Programming 2nd Edition.iso
/
OldSrc
/
CH6
/
SRC
/
BSPLINE.FRM
< prev
next >
Wrap
Text File
|
1996-04-01
|
11KB
|
416 lines
VERSION 4.00
Begin VB.Form BsplineForm
Caption = "B-spline"
ClientHeight = 5430
ClientLeft = 2175
ClientTop = 930
ClientWidth = 4830
Height = 6120
Left = 2115
LinkTopic = "Form1"
ScaleHeight = 362
ScaleMode = 3 'Pixel
ScaleWidth = 322
Top = 300
Width = 4950
Begin VB.CheckBox ShowTCheck
Caption = "Show t Values"
Height = 255
Left = 1680
TabIndex = 8
Top = 300
Width = 1755
End
Begin VB.TextBox KText
Height = 285
Left = 1140
TabIndex = 6
Text = "3"
Top = 45
Width = 375
End
Begin VB.CommandButton CmdNew
Caption = "New"
Enabled = 0 'False
Height = 375
Left = 4320
TabIndex = 5
Top = 0
Width = 495
End
Begin VB.CommandButton CmdGo
Caption = "Go"
Default = -1 'True
Enabled = 0 'False
Height = 375
Left = 3600
TabIndex = 4
Top = 0
Width = 495
End
Begin VB.CheckBox ControlCheck
Caption = "Show Control Points"
Height = 255
Left = 1680
TabIndex = 3
Top = 0
Value = 1 'Checked
Width = 1755
End
Begin VB.TextBox DtText
Height = 285
Left = 240
TabIndex = 2
Text = "0.05"
Top = 45
Width = 615
End
Begin VB.PictureBox Canvas
AutoRedraw = -1 'True
Height = 4815
Left = 0
ScaleHeight = 317
ScaleMode = 3 'Pixel
ScaleWidth = 317
TabIndex = 0
Top = 600
Width = 4815
End
Begin VB.Label Label1
Caption = "K"
Height = 255
Index = 0
Left = 960
TabIndex = 7
Top = 60
Width = 255
End
Begin VB.Label Label1
Caption = "dt"
Height = 255
Index = 1
Left = 0
TabIndex = 1
Top = 60
Width = 255
End
Begin VB.Menu mnuFile
Caption = "&File"
Begin VB.Menu mnuFileExit
Caption = "E&xit"
End
End
End
Attribute VB_Name = "BsplineForm"
Attribute VB_Creatable = False
Attribute VB_Exposed = False
Option Explicit
Const PI = 3.14159
Const GAP = 3
' The endpoints are points 1 and 4. The control
' points are points 2 and 3.
Dim MaxPt As Integer
Dim PtX() As Single
Dim PtY() As Single
Dim MakingNew As Boolean
' The index of the point being dragged.
Dim Dragging As Integer
Dim OldMode As Integer
' Kvalue determines the smoothness of the curve.
Dim Kvalue As Integer
' t runs between 0 and MaxPt - Kvalue + 2.
Dim MaxT As Single
' ************************************************
' Recursively compute the blending function.
' ************************************************
Function Blend(i As Integer, k As Integer, t As Single) As Single
Dim numer As Single
Dim denom As Single
Dim value1 As Single
Dim value2 As Single
' Base case for the recursion.
If k = 1 Then
If Knot(i) <= t And t < Knot(i + 1) Then
Blend = 1
ElseIf t = MaxT And Knot(i) <= t And t <= Knot(i + 1) Then
Blend = 1
Else
Blend = 0
End If
Exit Function
End If
denom = Knot(i + k - 1) - Knot(i)
If denom = 0 Then
value1 = 0
Else
numer = (t - Knot(i)) * Blend(i, k - 1, t)
value1 = numer / denom
End If
denom = Knot(i + k) - Knot(i + 1)
If denom = 0 Then
value2 = 0
Else
numer = (Knot(i + k) - t) * Blend(i + 1, k - 1, t)
value2 = numer / denom
End If
Blend = value1 + value2
End Function
' ************************************************
' Draw the curve on the indicated picture box.
' ************************************************
Sub DrawCurve(pic As PictureBox, start_t As Single, stop_t As Single, dt As Single)
Dim x1 As Single
Dim y1 As Single
Dim t As Single
x1 = X(start_t)
y1 = Y(start_t)
pic.Cls
pic.CurrentX = x1
pic.CurrentY = y1
t = start_t + dt
Do While t < stop_t
x1 = X(t)
y1 = Y(t)
pic.Line -(x1, y1)
t = t + dt
Loop
x1 = X(stop_t)
y1 = Y(stop_t)
pic.Line -(x1, y1)
End Sub
' ************************************************
' Return the ith knot value.
' ************************************************
Function Knot(i As Integer) As Integer
If i < Kvalue Then
Knot = 0
ElseIf i <= MaxPt Then
Knot = i - Kvalue + 1
Else
Knot = MaxPt - Kvalue + 2
End If
End Function
' ************************************************
' The parametric function Y(t).
' ************************************************
Function Y(t As Single) As Single
Dim i As Integer
Dim value As Single
For i = 0 To MaxPt
value = value + PtY(i) * Blend(i, Kvalue, t)
Next i
Y = value
End Function
' ************************************************
' The parametric function X(t).
' ************************************************
Function X(t As Single) As Single
Dim i As Integer
Dim value As Single
For i = 0 To MaxPt
value = value + PtX(i) * Blend(i, Kvalue, t)
Next i
X = value
End Function
' ************************************************
' Use DrawCurve to draw the Bezier curve.
' ************************************************
Private Sub DrawBspline()
Const DOTTED = 2
Dim dt As Single
Dim i As Integer
Dim oldstyle As Integer
If MaxPt < 0 Then Exit Sub
MousePointer = vbHourglass
Kvalue = CInt(KText.Text)
dt = CSng(DtText.Text)
MaxT = MaxPt - Kvalue + 2
DrawCurve Canvas, 0, MaxT, dt
If ControlCheck.value = vbChecked Then
' Draw the control points.
For i = 0 To MaxPt
Canvas.Line _
(PtX(i) - GAP, PtY(i) - GAP)- _
Step(2 * GAP, 2 * GAP), , BF
Next i
' Connect the control points.
oldstyle = Canvas.DrawStyle
Canvas.DrawStyle = DOTTED
Canvas.CurrentX = PtX(0)
Canvas.CurrentY = PtY(0)
For i = 1 To MaxPt
Canvas.Line -(PtX(i), PtY(i))
Next i
Canvas.DrawStyle = oldstyle
End If
' Mark the t values if desired.
If ShowTCheck.value = vbChecked Then
For dt = 0 To MaxT Step 1#
Canvas.Line (X(dt), Y(dt) - 5)-Step(0, 10)
Canvas.Line (X(dt) - 5, Y(dt))-Step(10, 0)
Next dt
End If
MousePointer = vbDefault
End Sub
' ************************************************
' Either collect a new point or select a point and
' start dragging it.
' ************************************************
Private Sub Canvas_MouseDown(button As Integer, Shift As Integer, X As Single, Y As Single)
Dim i As Integer
' If we are selecting points, do so now.
If MakingNew Then
MaxPt = MaxPt + 1
ReDim Preserve PtX(0 To MaxPt)
ReDim Preserve PtY(0 To MaxPt)
PtX(MaxPt) = X
PtY(MaxPt) = Y
Canvas.Line _
(X - GAP, Y - GAP)- _
Step(2 * GAP, 2 * GAP), , BF
If MaxPt >= 3 Then CmdGo.Enabled = True
Exit Sub
End If
' Otherwise start dragging a point.
' Find a close point.
For i = 0 To MaxPt
If Abs(PtX(i) - X) <= GAP And _
Abs(PtY(i) - Y) <= GAP Then Exit For
Next i
If i > MaxPt Then Exit Sub
Dragging = i
OldMode = Canvas.DrawMode
Canvas.DrawMode = vbInvert
PtX(Dragging) = X
PtY(Dragging) = Y
Canvas.Line _
(PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
Step(2 * GAP, 2 * GAP), , BF
End Sub
' ************************************************
' Continue dragging a point.
' ************************************************
Private Sub Canvas_MouseMove(button As Integer, Shift As Integer, X As Single, Y As Single)
If Dragging < 0 Then Exit Sub
Canvas.Line _
(PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
Step(2 * GAP, 2 * GAP), , BF
PtX(Dragging) = X
PtY(Dragging) = Y
Canvas.Line _
(PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
Step(2 * GAP, 2 * GAP), , BF
End Sub
' ************************************************
' Finish the drag and redraw the curve.
' ************************************************
Private Sub Canvas_MouseUp(button As Integer, Shift As Integer, X As Single, Y As Single)
If Dragging < 0 Then Exit Sub
Canvas.DrawMode = OldMode
PtX(Dragging) = X
PtY(Dragging) = Y
Dragging = -1
DrawBspline
End Sub
Private Sub CmdGo_Click()
MakingNew = False
CmdNew.Enabled = True
DrawBspline
End Sub
' ************************************************
' Prepare to get new points.
' ************************************************
Private Sub CmdNew_Click()
MaxPt = -1
CmdGo.Enabled = False
CmdNew.Enabled = False
MakingNew = True
Canvas.Cls
End Sub
Private Sub ControlCheck_Click()
DrawBspline
End Sub
Private Sub Form_Load()
MakingNew = True
MaxPt = -1
Dragging = -1
End Sub
' ************************************************
' Make the canvas as big as possible.
' ************************************************
Private Sub Form_Resize()
Canvas.Move 0, Canvas.Top, _
ScaleWidth, ScaleHeight - Canvas.Top
DrawBspline
End Sub
Private Sub mnuFileExit_Click()
Unload Me
End Sub
Private Sub ShowTCheck_Click()
DrawBspline
End Sub